Skip to content

Conversation

AZero13
Copy link
Contributor

@AZero13 AZero13 commented Oct 9, 2025

Cannot for thumb1 at this moment because of scheduler issues.

@llvmbot
Copy link
Member

llvmbot commented Oct 9, 2025

@llvm/pr-subscribers-backend-arm

Author: AZero13 (AZero13)

Changes

Patch is 43.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/162583.diff

8 Files Affected:

  • (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+31-40)
  • (modified) llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll (+78-88)
  • (modified) llvm/test/CodeGen/ARM/intrinsics-overflow.ll (+102-48)
  • (modified) llvm/test/CodeGen/ARM/sadd_sat.ll (+117-59)
  • (added) llvm/test/CodeGen/ARM/sadd_sat.s (+166)
  • (modified) llvm/test/CodeGen/ARM/sadd_sat_plus.ll (+5-5)
  • (modified) llvm/test/CodeGen/ARM/ssub_sat.ll (+34-31)
  • (modified) llvm/test/CodeGen/ARM/ssub_sat_plus.ll (+5-6)
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 2a40fb9b476f8..ca5a13b0a3345 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -4832,7 +4832,7 @@ SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
 }
 
 // This function returns three things: the arithmetic computation itself
-// (Value), a comparison (OverflowCmp), and a condition code (ARMcc).  The
+// (Value), a comparison (Overflow), and a condition code (ARMcc).  The
 // comparison and the condition code define the case in which the arithmetic
 // computation *does not* overflow.
 std::pair<SDValue, SDValue>
@@ -4840,42 +4840,30 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
                                  SDValue &ARMcc) const {
   assert(Op.getValueType() == MVT::i32 &&  "Unsupported value type");
 
-  SDValue Value, OverflowCmp;
+  SDValue Value, Overflow;
   SDValue LHS = Op.getOperand(0);
   SDValue RHS = Op.getOperand(1);
   SDLoc dl(Op);
-
-  // FIXME: We are currently always generating CMPs because we don't support
-  // generating CMN through the backend. This is not as good as the natural
-  // CMP case because it causes a register dependency and cannot be folded
-  // later.
+  unsigned Opc = 0;
 
   switch (Op.getOpcode()) {
   default:
     llvm_unreachable("Unknown overflow instruction!");
   case ISD::SADDO:
+    Opc = ARMISD::ADDC;
     ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
-    Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
-    OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
     break;
   case ISD::UADDO:
-    ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
-    // We use ADDC here to correspond to its use in LowerUnsignedALUO.
-    // We do not use it in the USUBO case as Value may not be used.
-    Value = DAG.getNode(ARMISD::ADDC, dl,
-                        DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
-                .getValue(0);
-    OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
+    Opc = ARMISD::ADDC;
+    ARMcc = DAG.getConstant(ARMCC::LO, dl, MVT::i32);
     break;
   case ISD::SSUBO:
+    Opc = ARMISD::SUBC;
     ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
-    Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
-    OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
     break;
   case ISD::USUBO:
+    Opc = ARMISD::SUBC;
     ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
-    Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
-    OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
     break;
   case ISD::UMULO:
     // We generate a UMUL_LOHI and then check if the high word is 0.
@@ -4883,7 +4871,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
     Value = DAG.getNode(ISD::UMUL_LOHI, dl,
                         DAG.getVTList(Op.getValueType(), Op.getValueType()),
                         LHS, RHS);
-    OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
+    Overflow = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
                               DAG.getConstant(0, dl, MVT::i32));
     Value = Value.getValue(0); // We only want the low 32 bits for the result.
     break;
@@ -4894,15 +4882,20 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
     Value = DAG.getNode(ISD::SMUL_LOHI, dl,
                         DAG.getVTList(Op.getValueType(), Op.getValueType()),
                         LHS, RHS);
-    OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
+    Overflow = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
                               DAG.getNode(ISD::SRA, dl, Op.getValueType(),
                                           Value.getValue(0),
                                           DAG.getConstant(31, dl, MVT::i32)));
     Value = Value.getValue(0); // We only want the low 32 bits for the result.
     break;
   } // switch (...)
+  if (Opc) {
+    SDVTList VTs = DAG.getVTList(Op.getValueType(), FlagsVT);
+    Value = DAG.getNode(Opc, dl, VTs, LHS, RHS);
+    Overflow = Value.getValue(1);
+  }
 
-  return std::make_pair(Value, OverflowCmp);
+  return std::make_pair(Value, Overflow);
 }
 
 SDValue
@@ -4911,20 +4904,18 @@ ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
   if (!isTypeLegal(Op.getValueType()))
     return SDValue();
 
-  SDValue Value, OverflowCmp;
-  SDValue ARMcc;
-  std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
   SDLoc dl(Op);
+  SDValue Value, Overflow;
+  SDValue ARMcc;
+  std::tie(Value, Overflow) = getARMXALUOOp(Op, DAG, ARMcc);
   // We use 0 and 1 as false and true values.
   SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
   SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
-  EVT VT = Op.getValueType();
 
-  SDValue Overflow =
-      DAG.getNode(ARMISD::CMOV, dl, VT, TVal, FVal, ARMcc, OverflowCmp);
+  Overflow =
+      DAG.getNode(ARMISD::CMOV, dl, MVT::i32, TVal, FVal, ARMcc, Overflow);
 
-  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
-  return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
+  return DAG.getMergeValues({Value, Overflow}, dl);
 }
 
 static SDValue ConvertBooleanCarryToCarryFlag(SDValue BoolCarry,
@@ -5055,12 +5046,12 @@ SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
     if (!isTypeLegal(Cond->getValueType(0)))
       return SDValue();
 
-    SDValue Value, OverflowCmp;
+    SDValue Value, Overflow;
     SDValue ARMcc;
-    std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
+    std::tie(Value, Overflow) = getARMXALUOOp(Cond, DAG, ARMcc);
     EVT VT = Op.getValueType();
 
-    return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
+    return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, Overflow, DAG);
   }
 
   // Convert:
@@ -5657,9 +5648,9 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
       return SDValue();
 
     // The actual operation with overflow check.
-    SDValue Value, OverflowCmp;
+    SDValue Value, Overflow;
     SDValue ARMcc;
-    std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
+    std::tie(Value, Overflow) = getARMXALUOOp(Cond, DAG, ARMcc);
 
     // Reverse the condition code.
     ARMCC::CondCodes CondCode =
@@ -5668,7 +5659,7 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
     ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
 
     return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
-                       OverflowCmp);
+                       Overflow);
   }
 
   return SDValue();
@@ -5707,9 +5698,9 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
       return SDValue();
 
     // The actual operation with overflow check.
-    SDValue Value, OverflowCmp;
+    SDValue Value, Overflow;
     SDValue ARMcc;
-    std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
+    std::tie(Value, Overflow) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
 
     if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
       // Reverse the condition code.
@@ -5720,7 +5711,7 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
     }
 
     return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
-                       OverflowCmp);
+                       Overflow);
   }
 
   if (LHS.getValueType() == MVT::i32) {
diff --git a/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll b/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
index b92f03d43bb4c..a40a6c2db490f 100644
--- a/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
+++ b/llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll
@@ -20,10 +20,10 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; ENABLE-NEXT:    .save {r11, lr}
 ; ENABLE-NEXT:    push {r11, lr}
 ; ENABLE-NEXT:    cmn r1, #1
-; ENABLE-NEXT:    ble .LBB0_7
+; ENABLE-NEXT:    ble .LBB0_6
 ; ENABLE-NEXT:  @ %bb.1: @ %while.cond.preheader
 ; ENABLE-NEXT:    cmp r1, #0
-; ENABLE-NEXT:    beq .LBB0_6
+; ENABLE-NEXT:    beq .LBB0_5
 ; ENABLE-NEXT:  @ %bb.2: @ %while.cond.preheader
 ; ENABLE-NEXT:    cmp r0, r2
 ; ENABLE-NEXT:    pophs {r11, pc}
@@ -34,74 +34,69 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; ENABLE-NEXT:  .LBB0_4: @ %while.body
 ; ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
 ; ENABLE-NEXT:    ldrb r3, [r0]
+; ENABLE-NEXT:    subs r1, r1, #1
 ; ENABLE-NEXT:    ldrb r3, [r12, r3]
 ; ENABLE-NEXT:    add r0, r0, r3
-; ENABLE-NEXT:    sub r3, r1, #1
-; ENABLE-NEXT:    cmp r3, r1
-; ENABLE-NEXT:    bhs .LBB0_6
-; ENABLE-NEXT:  @ %bb.5: @ %while.body
-; ENABLE-NEXT:    @ in Loop: Header=BB0_4 Depth=1
-; ENABLE-NEXT:    mov r1, r3
-; ENABLE-NEXT:    cmp r0, r2
+; ENABLE-NEXT:    cmplo r0, r2
 ; ENABLE-NEXT:    blo .LBB0_4
-; ENABLE-NEXT:  .LBB0_6: @ %if.end29
+; ENABLE-NEXT:  .LBB0_5: @ %if.end29
 ; ENABLE-NEXT:    pop {r11, pc}
-; ENABLE-NEXT:  .LBB0_7: @ %while.cond2.outer
+; ENABLE-NEXT:  .LBB0_6: @ %while.cond2.outer
 ; ENABLE-NEXT:    @ =>This Loop Header: Depth=1
-; ENABLE-NEXT:    @ Child Loop BB0_8 Depth 2
-; ENABLE-NEXT:    @ Child Loop BB0_15 Depth 2
+; ENABLE-NEXT:    @ Child Loop BB0_7 Depth 2
+; ENABLE-NEXT:    @ Child Loop BB0_14 Depth 2
 ; ENABLE-NEXT:    mov r3, r0
-; ENABLE-NEXT:  .LBB0_8: @ %while.cond2
-; ENABLE-NEXT:    @ Parent Loop BB0_7 Depth=1
+; ENABLE-NEXT:  .LBB0_7: @ %while.cond2
+; ENABLE-NEXT:    @ Parent Loop BB0_6 Depth=1
 ; ENABLE-NEXT:    @ => This Inner Loop Header: Depth=2
 ; ENABLE-NEXT:    add r1, r1, #1
 ; ENABLE-NEXT:    cmp r1, #1
-; ENABLE-NEXT:    beq .LBB0_18
-; ENABLE-NEXT:  @ %bb.9: @ %while.body4
-; ENABLE-NEXT:    @ in Loop: Header=BB0_8 Depth=2
+; ENABLE-NEXT:    beq .LBB0_17
+; ENABLE-NEXT:  @ %bb.8: @ %while.body4
+; ENABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=2
 ; ENABLE-NEXT:    cmp r3, r2
-; ENABLE-NEXT:    bls .LBB0_8
-; ENABLE-NEXT:  @ %bb.10: @ %if.then7
-; ENABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; ENABLE-NEXT:    bls .LBB0_7
+; ENABLE-NEXT:  @ %bb.9: @ %if.then7
+; ENABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; ENABLE-NEXT:    mov r0, r3
 ; ENABLE-NEXT:    ldrb r12, [r0, #-1]!
 ; ENABLE-NEXT:    sxtb lr, r12
 ; ENABLE-NEXT:    cmn lr, #1
-; ENABLE-NEXT:    bgt .LBB0_7
-; ENABLE-NEXT:  @ %bb.11: @ %if.then7
-; ENABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; ENABLE-NEXT:    bgt .LBB0_6
+; ENABLE-NEXT:  @ %bb.10: @ %if.then7
+; ENABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; ENABLE-NEXT:    cmp r0, r2
-; ENABLE-NEXT:    bls .LBB0_7
-; ENABLE-NEXT:  @ %bb.12: @ %land.rhs14.preheader
-; ENABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; ENABLE-NEXT:    bls .LBB0_6
+; ENABLE-NEXT:  @ %bb.11: @ %land.rhs14.preheader
+; ENABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; ENABLE-NEXT:    cmn lr, #1
-; ENABLE-NEXT:    bgt .LBB0_7
-; ENABLE-NEXT:  @ %bb.13: @ %land.rhs14.preheader
-; ENABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; ENABLE-NEXT:    bgt .LBB0_6
+; ENABLE-NEXT:  @ %bb.12: @ %land.rhs14.preheader
+; ENABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; ENABLE-NEXT:    cmp r12, #191
-; ENABLE-NEXT:    bhi .LBB0_7
-; ENABLE-NEXT:  @ %bb.14: @ %while.body24.preheader
-; ENABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; ENABLE-NEXT:    bhi .LBB0_6
+; ENABLE-NEXT:  @ %bb.13: @ %while.body24.preheader
+; ENABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; ENABLE-NEXT:    sub r3, r3, #2
-; ENABLE-NEXT:  .LBB0_15: @ %while.body24
-; ENABLE-NEXT:    @ Parent Loop BB0_7 Depth=1
+; ENABLE-NEXT:  .LBB0_14: @ %while.body24
+; ENABLE-NEXT:    @ Parent Loop BB0_6 Depth=1
 ; ENABLE-NEXT:    @ => This Inner Loop Header: Depth=2
 ; ENABLE-NEXT:    mov r0, r3
 ; ENABLE-NEXT:    cmp r3, r2
-; ENABLE-NEXT:    bls .LBB0_7
-; ENABLE-NEXT:  @ %bb.16: @ %while.body24.land.rhs14_crit_edge
-; ENABLE-NEXT:    @ in Loop: Header=BB0_15 Depth=2
+; ENABLE-NEXT:    bls .LBB0_6
+; ENABLE-NEXT:  @ %bb.15: @ %while.body24.land.rhs14_crit_edge
+; ENABLE-NEXT:    @ in Loop: Header=BB0_14 Depth=2
 ; ENABLE-NEXT:    mov r3, r0
 ; ENABLE-NEXT:    ldrsb lr, [r3], #-1
 ; ENABLE-NEXT:    cmn lr, #1
 ; ENABLE-NEXT:    uxtb r12, lr
-; ENABLE-NEXT:    bgt .LBB0_7
-; ENABLE-NEXT:  @ %bb.17: @ %while.body24.land.rhs14_crit_edge
-; ENABLE-NEXT:    @ in Loop: Header=BB0_15 Depth=2
+; ENABLE-NEXT:    bgt .LBB0_6
+; ENABLE-NEXT:  @ %bb.16: @ %while.body24.land.rhs14_crit_edge
+; ENABLE-NEXT:    @ in Loop: Header=BB0_14 Depth=2
 ; ENABLE-NEXT:    cmp r12, #192
-; ENABLE-NEXT:    blo .LBB0_15
-; ENABLE-NEXT:    b .LBB0_7
-; ENABLE-NEXT:  .LBB0_18:
+; ENABLE-NEXT:    blo .LBB0_14
+; ENABLE-NEXT:    b .LBB0_6
+; ENABLE-NEXT:  .LBB0_17:
 ; ENABLE-NEXT:    mov r0, r3
 ; ENABLE-NEXT:    pop {r11, pc}
 ;
@@ -110,10 +105,10 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; DISABLE-NEXT:    .save {r11, lr}
 ; DISABLE-NEXT:    push {r11, lr}
 ; DISABLE-NEXT:    cmn r1, #1
-; DISABLE-NEXT:    ble .LBB0_7
+; DISABLE-NEXT:    ble .LBB0_6
 ; DISABLE-NEXT:  @ %bb.1: @ %while.cond.preheader
 ; DISABLE-NEXT:    cmp r1, #0
-; DISABLE-NEXT:    beq .LBB0_6
+; DISABLE-NEXT:    beq .LBB0_5
 ; DISABLE-NEXT:  @ %bb.2: @ %while.cond.preheader
 ; DISABLE-NEXT:    cmp r0, r2
 ; DISABLE-NEXT:    pophs {r11, pc}
@@ -124,74 +119,69 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
 ; DISABLE-NEXT:  .LBB0_4: @ %while.body
 ; DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
 ; DISABLE-NEXT:    ldrb r3, [r0]
+; DISABLE-NEXT:    subs r1, r1, #1
 ; DISABLE-NEXT:    ldrb r3, [r12, r3]
 ; DISABLE-NEXT:    add r0, r0, r3
-; DISABLE-NEXT:    sub r3, r1, #1
-; DISABLE-NEXT:    cmp r3, r1
-; DISABLE-NEXT:    bhs .LBB0_6
-; DISABLE-NEXT:  @ %bb.5: @ %while.body
-; DISABLE-NEXT:    @ in Loop: Header=BB0_4 Depth=1
-; DISABLE-NEXT:    mov r1, r3
-; DISABLE-NEXT:    cmp r0, r2
+; DISABLE-NEXT:    cmplo r0, r2
 ; DISABLE-NEXT:    blo .LBB0_4
-; DISABLE-NEXT:  .LBB0_6: @ %if.end29
+; DISABLE-NEXT:  .LBB0_5: @ %if.end29
 ; DISABLE-NEXT:    pop {r11, pc}
-; DISABLE-NEXT:  .LBB0_7: @ %while.cond2.outer
+; DISABLE-NEXT:  .LBB0_6: @ %while.cond2.outer
 ; DISABLE-NEXT:    @ =>This Loop Header: Depth=1
-; DISABLE-NEXT:    @ Child Loop BB0_8 Depth 2
-; DISABLE-NEXT:    @ Child Loop BB0_15 Depth 2
+; DISABLE-NEXT:    @ Child Loop BB0_7 Depth 2
+; DISABLE-NEXT:    @ Child Loop BB0_14 Depth 2
 ; DISABLE-NEXT:    mov r3, r0
-; DISABLE-NEXT:  .LBB0_8: @ %while.cond2
-; DISABLE-NEXT:    @ Parent Loop BB0_7 Depth=1
+; DISABLE-NEXT:  .LBB0_7: @ %while.cond2
+; DISABLE-NEXT:    @ Parent Loop BB0_6 Depth=1
 ; DISABLE-NEXT:    @ => This Inner Loop Header: Depth=2
 ; DISABLE-NEXT:    add r1, r1, #1
 ; DISABLE-NEXT:    cmp r1, #1
-; DISABLE-NEXT:    beq .LBB0_18
-; DISABLE-NEXT:  @ %bb.9: @ %while.body4
-; DISABLE-NEXT:    @ in Loop: Header=BB0_8 Depth=2
+; DISABLE-NEXT:    beq .LBB0_17
+; DISABLE-NEXT:  @ %bb.8: @ %while.body4
+; DISABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=2
 ; DISABLE-NEXT:    cmp r3, r2
-; DISABLE-NEXT:    bls .LBB0_8
-; DISABLE-NEXT:  @ %bb.10: @ %if.then7
-; DISABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; DISABLE-NEXT:    bls .LBB0_7
+; DISABLE-NEXT:  @ %bb.9: @ %if.then7
+; DISABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; DISABLE-NEXT:    mov r0, r3
 ; DISABLE-NEXT:    ldrb r12, [r0, #-1]!
 ; DISABLE-NEXT:    sxtb lr, r12
 ; DISABLE-NEXT:    cmn lr, #1
-; DISABLE-NEXT:    bgt .LBB0_7
-; DISABLE-NEXT:  @ %bb.11: @ %if.then7
-; DISABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; DISABLE-NEXT:    bgt .LBB0_6
+; DISABLE-NEXT:  @ %bb.10: @ %if.then7
+; DISABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; DISABLE-NEXT:    cmp r0, r2
-; DISABLE-NEXT:    bls .LBB0_7
-; DISABLE-NEXT:  @ %bb.12: @ %land.rhs14.preheader
-; DISABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; DISABLE-NEXT:    bls .LBB0_6
+; DISABLE-NEXT:  @ %bb.11: @ %land.rhs14.preheader
+; DISABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; DISABLE-NEXT:    cmn lr, #1
-; DISABLE-NEXT:    bgt .LBB0_7
-; DISABLE-NEXT:  @ %bb.13: @ %land.rhs14.preheader
-; DISABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; DISABLE-NEXT:    bgt .LBB0_6
+; DISABLE-NEXT:  @ %bb.12: @ %land.rhs14.preheader
+; DISABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; DISABLE-NEXT:    cmp r12, #191
-; DISABLE-NEXT:    bhi .LBB0_7
-; DISABLE-NEXT:  @ %bb.14: @ %while.body24.preheader
-; DISABLE-NEXT:    @ in Loop: Header=BB0_7 Depth=1
+; DISABLE-NEXT:    bhi .LBB0_6
+; DISABLE-NEXT:  @ %bb.13: @ %while.body24.preheader
+; DISABLE-NEXT:    @ in Loop: Header=BB0_6 Depth=1
 ; DISABLE-NEXT:    sub r3, r3, #2
-; DISABLE-NEXT:  .LBB0_15: @ %while.body24
-; DISABLE-NEXT:    @ Parent Loop BB0_7 Depth=1
+; DISABLE-NEXT:  .LBB0_14: @ %while.body24
+; DISABLE-NEXT:    @ Parent Loop BB0_6 Depth=1
 ; DISABLE-NEXT:    @ => This Inner Loop Header: Depth=2
 ; DISABLE-NEXT:    mov r0, r3
 ; DISABLE-NEXT:    cmp r3, r2
-; DISABLE-NEXT:    bls .LBB0_7
-; DISABLE-NEXT:  @ %bb.16: @ %while.body24.land.rhs14_crit_edge
-; DISABLE-NEXT:    @ in Loop: Header=BB0_15 Depth=2
+; DISABLE-NEXT:    bls .LBB0_6
+; DISABLE-NEXT:  @ %bb.15: @ %while.body24.land.rhs14_crit_edge
+; DISABLE-NEXT:    @ in Loop: Header=BB0_14 Depth=2
 ; DISABLE-NEXT:    mov r3, r0
 ; DISABLE-NEXT:    ldrsb lr, [r3], #-1
 ; DISABLE-NEXT:    cmn lr, #1
 ; DISABLE-NEXT:    uxtb r12, lr
-; DISABLE-NEXT:    bgt .LBB0_7
-; DISABLE-NEXT:  @ %bb.17: @ %while.body24.land.rhs14_crit_edge
-; DISABLE-NEXT:    @ in Loop: Header=BB0_15 Depth=2
+; DISABLE-NEXT:    bgt .LBB0_6
+; DISABLE-NEXT:  @ %bb.16: @ %while.body24.land.rhs14_crit_edge
+; DISABLE-NEXT:    @ in Loop: Header=BB0_14 Depth=2
 ; DISABLE-NEXT:    cmp r12, #192
-; DISABLE-NEXT:    blo .LBB0_15
-; DISABLE-NEXT:    b .LBB0_7
-; DISABLE-NEXT:  .LBB0_18:
+; DISABLE-NEXT:    blo .LBB0_14
+; DISABLE-NEXT:    b .LBB0_6
+; DISABLE-NEXT:  .LBB0_17:
 ; DISABLE-NEXT:    mov r0, r3
 ; DISABLE-NEXT:    pop {r11, pc}
 entry:
diff --git a/llvm/test/CodeGen/ARM/intrinsics-overflow.ll b/llvm/test/CodeGen/ARM/intrinsics-overflow.ll
index 8bd78dd0f6ab5..49a6daf9578cb 100644
--- a/llvm/test/CodeGen/ARM/intrinsics-overflow.ll
+++ b/llvm/test/CodeGen/ARM/intrinsics-overflow.ll
@@ -1,104 +1,158 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; RUN: llc < %s -mtriple=arm-linux -mcpu=generic -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
 ; RUN: llc < %s -mtriple=thumbv6m-eabi -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=THUMBV6
 ; RUN: llc < %s -mtriple=thumbv7-eabi -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=THUMBV7
 
 define i32 @uadd_overflow(i32 %a, i32 %b) #0 {
+; ARM-LABEL: uadd_overflow:
+; ARM:       @ %bb.0:
+; ARM-NEXT:    adds r0, r0, r1
+; ARM-NEXT:    mov r2, #0
+; ARM-NEXT:    adc r0, r2, #0
+; ARM-NEXT:    mov pc, lr
+;
+; THUMBV6-LABEL: uadd_overflow:
+; THUMBV6:       @ %bb.0:
+; THUMBV6-NEXT:    movs r2, #0
+; THUMBV6-NEXT:    adds r0, r0, r1
+; THUMBV6-NEXT:    adcs r2, r2
+; THUMBV6-NEXT:    mov r0, r2
+; THUMBV6-NEXT:    bx lr
+;
+; THUMBV7-LABEL: uadd_overflow:
+; THUMBV7:       @ %bb.0:
+; THUMBV7-NEXT:    adds r0, r0, r1
+; THUMBV7-NEXT:    mov.w r2, #0
+; THUMBV7-NEXT:    adc r0, r2, #0
+; THUMBV7-NEXT:    bx lr
   %sadd = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b)
   %1 = extractvalue { i32, i1 } %sadd, 1
   %2 = zext i1 %1 to i32
   ret i32 %2
 
-  ; CHECK-LABEL: uadd_overflow:
 
-  ; ARM: adds r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
-  ; ARM: mov r[[R2:[0-9]+]], #0
-  ; ARM: adc r[[R0]], r[[R2]], #0
 
-  ; THUMBV6: movs    r[[R2:[0-9]+]], #0
-  ; THUMBV6: adds    r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
-  ; THUMBV6: adcs    r[[R2]], r[[R2]]
-  ; THUMBV6: mov     r[[R0]], r[[R2]]
 
-  ; THUMBV7: adds  r[[R0:[0-9]+]], r[[R0]], r[[R1:[0-9]+]]
-  ; THUMBV7: mov.w r[[R2:[0-9]+]], #0
-  ; THUMBV7: adc   r[[R0]], r[[R2]], #0
 }
 
 
 define i32 @sadd_overflow(i32 %a, i32 %b) #0 {
+; ARM-LABEL: sadd_overflow:
+; ARM:       @ %bb.0:
+; ARM-NEXT:    mov r2, #1
+; ARM-NEXT:    adds r0, r0, r1
+; ARM-NEXT:    movvc r2, #0
+; ARM-NEXT:    mov r0, r2
+; ARM-NEXT:    mov pc, lr
+;
+; THUMBV6-LABEL: sadd_overflow:
+; THUMBV6:       @ %bb.0:
+; THUMBV6-NEXT:    adds r0, r0, r1
+; THUMBV6-NEXT:    bvc .LBB1_2
+; THU...
[truncated]

@AZero13 AZero13 marked this pull request as draft October 9, 2025 02:04
Copy link

github-actions bot commented Oct 9, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@AZero13 AZero13 force-pushed the addos branch 3 times, most recently from cb8b057 to 190db4b Compare October 9, 2025 19:37
Cannot for thumb1 at this moment because of scheduler issues.
@AZero13 AZero13 marked this pull request as ready for review October 9, 2025 19:43
@AZero13 AZero13 changed the title Use addc nodes when lowering overflow [ARM] Use addc nodes when lowering overflow Oct 9, 2025
@AZero13
Copy link
Contributor Author

AZero13 commented Oct 9, 2025

@davemgreen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants